
import { _decorator, AnimationClip, Component, Node, Size, Sprite, SpriteFrame, UITransform, Vec2, Vec3 } from 'cc';
import { Singleton } from '../../tools/Singleton';
import { bullet_config, secondGun_specialSkill_config } from '../../manager/AppControll';
import { bulletManger } from '../bullet/BulletManager';
import { Loader } from '../../tools/LoadManger';
import { BulletNormal } from '../bullet/BulletNormal';
import { Move } from '../component/Move';
import { SkillMissile } from './SkillMissile';
import { DamageStruct } from '../FightControl';
import { SkillLightning } from './SkillLightning';
import { MonsterManager } from '../monster/MonsterManager';
import { SkillLaser } from './SkillLaser';
import { DataHelper } from '../../system/DataHelper';
import { Tools } from '../../tools/Tools';
const { ccclass, property } = _decorator;

export enum SkillType {
    SkillLightning = 3,
    SkillLaser = 2,
    SkillMissile = 1,
}

type NodeData = {
    node: Node;
    distance: number;
}

@ccclass('SkillManager')
export class SkillManager extends Singleton<SkillManager> {
    private mSkillConig: secondGun_specialSkill_config = null;
    private mStartPosition: Vec3 = null
    private mTarget: Node = null;
    private mNdSkill: Node = null;
    protected mAnclp: AnimationClip = null;
    protected mStrPath: string = "bullet/"
    protected mAnSpf: SpriteFrame[] = [];
    protected mSpeed: number = 0;



    InitSkillManager(node: Node) {
        this.mNdSkill = node;
    }

    CastSkill(config: secondGun_specialSkill_config, eulerAngles: Vec3, startV3: Vec3, endPoint: Vec2, target: Node, dmg: DamageStruct) {
        this.mStartPosition = startV3;
        this.mSkillConig = config;
        this.mTarget = target;
        this.mSpeed = this.mSkillConig.skillSpeed;
        switch (config.skillType) {
            case SkillType.SkillMissile:
                this.CreateMissile(startV3, eulerAngles, endPoint, dmg);
                break;
            case SkillType.SkillLaser:
                this.CreateLaser(startV3, endPoint, dmg);
                break;
            case SkillType.SkillLightning:
                this.CreateLightning(startV3, dmg, target);
                break;

        }
    }

    CreateMissile(startV3, eulerAngles, endPoint, dmg: DamageStruct) {
        if (!this.mSkillConig.skillBullet) return;
        let bullet: bullet_config = DataHelper.GetBulletConfig(this.mSkillConig.skillBullet);
        Loader.LoadBulletImage(this.mStrPath + bullet.rightPosition, (spf) => {
            let node = new Node();
            node.addComponent(Sprite);
            node.getComponent(Sprite).spriteFrame = spf;
            node.getComponent(Sprite).sizeMode = Sprite.SizeMode.CUSTOM;
            node.getComponent(Sprite).trim = false;
            node.getComponent(UITransform).contentSize = new Size(bullet.bulletSize[0], bullet.bulletSize[1]);
            node.position = new Vec3(startV3.x, startV3.y, 0);
            node.eulerAngles = this.RevisioEuler(eulerAngles.clone());
            node.active = true;
            node.layer = 1 << 25;
            this.mNdSkill.addChild(node);
            node.addComponent(Move).InitPoint(new Vec2(startV3.x, startV3.y), endPoint, this.mSpeed);
            node.addComponent(SkillMissile).InitSkill(this.mSkillConig, dmg);
        })
    }

    CreateLightning(startV3, dmg: DamageStruct, target: Node) {
        let lt = this.findNearestNodes(Tools.GetLtMonster(), new Vec2(startV3.x, startV3.y), this.mSkillConig.skillNum[0], target)
        lt.forEach(monster => {
            let node = new Node();
            node.addComponent(Sprite);
            node.getComponent(Sprite).sizeMode = Sprite.SizeMode.CUSTOM;
            node.getComponent(Sprite).trim = true;
            node.active = true;
            node.layer = 1 << 25;
            this.mNdSkill.addChild(node);
            node.position = new Vec3(startV3.x, startV3.y, 0);
            node.getComponent(UITransform).anchorPoint = new Vec2(0.5, 0);
            node.addComponent(SkillLightning).InitAnData(startV3, monster);
            node.getComponent(SkillLightning).InitSkill(this.mSkillConig, dmg);
        })
    }

    CreateLaser(startV3, endPoint, dmg: DamageStruct) {
        let node = new Node();
        node.addComponent(Sprite);
        node.getComponent(Sprite).sizeMode = Sprite.SizeMode.CUSTOM;
        node.getComponent(Sprite).trim = false;
        node.active = true;
        node.layer = 1 << 25;
        this.mNdSkill.addChild(node);
        node.position = new Vec3(startV3.x, startV3.y, 0);
        node.getComponent(UITransform).anchorPoint = new Vec2(1, 0.5);
        node.addComponent(SkillLaser).InitAnData(startV3, endPoint);
        node.getComponent(SkillLaser).InitSkill(this.mSkillConig, dmg);
    }

    findNearestNodes(ltNode: Node[], root: Vec2, count, target: Node): Node[] {
        const nodeDataList: NodeData[] = [];
        // 计算节点之间的距离并存储到数组中
        for (const node of ltNode) {
            const distance = Vec2.distance(new Vec2(node.position.x, node.position.y), root);
            nodeDataList.push({ node, distance });
        }

        // 根据距离排序节点数组
        nodeDataList.sort((a, b) => a.distance - b.distance);
        // 截取前五个最近的节点
        const nearestNodes = nodeDataList.slice(0, count).map(data => data.node);

        if (target) {
            nearestNodes[nearestNodes.length - 1] = target;
        }

        return nearestNodes;
    }

    RevisioEuler(eulerAngles: Vec3) {
        if (eulerAngles.z <= 90 && eulerAngles.z >= 0) {
            eulerAngles.add(new Vec3(0, 0, -90));
        } else if (eulerAngles.z <= 0 && eulerAngles.z >= -90) {
            eulerAngles.add(new Vec3(0, 0, 90));
        }
        return eulerAngles;
    }
}

/**
 * [1] Class member could be defined like this.
 * [2] Use `property` decorator if your want the member to be serializable.
 * [3] Your initialization goes here.
 * [4] Your update function goes here.
 *
 * Learn more about scripting: https://docs.cocos.com/creator/3.4/manual/zh/scripting/
 * Learn more about CCClass: https://docs.cocos.com/creator/3.4/manual/zh/scripting/decorator.html
 * Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.4/manual/zh/scripting/life-cycle-callbacks.html
 */
